package com.ruoyi.biz.service.diskfile.impl;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;

import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.ruoyi.biz.service.diskfile.IFileItemStoreService;
import com.ruoyi.common.config.RuoYiConfig;

@Service
public class FileItemStoreServiceImpl implements IFileItemStoreService {

	private Path root;//Paths.get("./uploads");

	@Override
	public void init() {
		try {
			root = Paths.get(RuoYiConfig.getUploadPath());
			Files.createDirectories(root);
		} catch (IOException e) {
			throw new RuntimeException("Could not initialize folder for upload!");
		}
	}

	@Override
	public void save(MultipartFile file, String sub) {
		try {
			Path root_n = root.resolve(sub);
			if (!Files.exists(root_n)) {
				try {
					Files.createDirectories(root_n);
				} catch (IOException e) {
					throw new RuntimeException(e.getMessage());
				}
			}

			Files.copy(file.getInputStream(), root_n.resolve(file.getOriginalFilename()));
		} catch (Exception e) {
			if (e instanceof FileAlreadyExistsException) {
				throw new RuntimeException("A file of that name already exists.");
			}

			throw new RuntimeException(e.getMessage());
		}
	}

	@Override
	public Resource load(String filename, String sub) {
		try {
			Path root_n = root.resolve(sub);
			Path file = root_n.resolve(filename);
			Resource resource = new UrlResource(file.toUri());

			if (resource.exists() || resource.isReadable()) {
				return resource;
			} else {
				throw new RuntimeException("Could not read the file!");
			}
		} catch (MalformedURLException e) {
			throw new RuntimeException("Error: " + e.getMessage());
		}
	}

	@Override
	public boolean delete(String filename, String sub) {
		try {
			Path root_n = root.resolve(sub);
			Path file = root_n.resolve(filename);
			return Files.deleteIfExists(file);
		} catch (IOException e) {
			throw new RuntimeException("Error: " + e.getMessage());
		}
	}

	@Override
	public Stream<Path> loadAll(String sub) {
		try {
			Path root_n = root.resolve(sub);
			boolean pathExists = Files.exists(root_n, new LinkOption[] { LinkOption.NOFOLLOW_LINKS });
			if (pathExists) {
				return Files.walk(root_n, 1).filter(path -> !path.equals(root_n)).map(root_n::relativize);
			} else {
				return null;
			}
		} catch (IOException e) {
			// throw new RuntimeException("Could not load the files!");
			return null;
		}
	}

}
